package values

import (
	"fmt"

	"soluty.cc/go/xlog"
)

// 外部使用values库Calc, 使用方法 NewAttribute addNumber addNumber reset
func Calc(formula Formula) error {
	for _, value := range formula.Attrs() {
		err := value.SetFormula(formula)
		if err != nil {
			return xlog.Errorf(xlog.Fmt(), toString(formula), err)
		}
	}
	err := formula.Calculate()
	if err != nil {
		return xlog.Errorf(xlog.Fmt(), toString(formula), err)
	}
	for _, value := range formula.Attrs() {
		err := value.Reset()
		if err != nil {
			return xlog.Errorf(xlog.Fmt(), toString(formula), err)
		}
	}
	return nil
}

// 公式， 所有的属性， 要么在公式中， 要么不在公式中
type Formula interface {
	Calculate() error    // 公式的计算方法
	AttrNames() []string // 公式用到了什么属性名称
	Attrs() []*Attribute // 公式中有哪些属性
}

// 公式的String方法
func toString(f Formula) string {
	s := fmt.Sprintf("%v: 涉及属性的详情如下\n", f)
	for _, attr := range f.Attrs() {
		s += fmt.Sprintf("%v的属性:\n", attr.holder)
		for _, attrName := range f.AttrNames() {
			number := attr.Attr(attrName)
			if number == nil {
				continue
			}
			s += fmt.Sprintf("%v__%v\n", attrName, number)
		}
	}
	return s
}
